/*
    Copyright 2006-2011 Patrik Jonsson, sunrise@familjenjonsson.org

    This file is part of Sunrise.

    Sunrise is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    Sunrise is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Sunrise.  If not, see <http://www.gnu.org/licenses/>.

*/

/// \file
/// Contains declaration of CUDA temperature and SED calculation functions.

// $Id$

#ifndef __cuda_grain_temp__
#define __cuda_grain_temp__

/** The mcrxcuda namespace contains CUDA stuff. */
namespace mcrxcuda {
  typedef float T_float;

/** This function calculates the SED for equilibrium grains using
    CUDA. The 2D arrays are row-major in (r,c) format, ordered as
    follows: (e)sigma(s,l), intensity(c,l), sed(c,l). If add_to_sed
    is true, the SED will be added to existing data in the sed array,
    otherwise it is overwritten. The accuracy of the temperature
    solution should be supplied. If pointers for heating and temp are
    supplied, those data are also returned, ordered as (s,c). */
  template<typename T_input>
  unsigned int calculate_equilibrium_SED(const T_input* sigma, 
					 const T_input* esigma, 
					 const T_input* intensity, 
					 const T_input* lambda, 
					 const T_input* elambda, 
					 const T_input* size,
					 const T_input* m_dust, 
					 const T_input* dn,
					 T_input* sed,
					 size_t ns, size_t nc, 
					 size_t nl, size_t nel, 
					 bool add_to_sed, T_float accuracy,
					 T_float sed_norm = 1.0,
					 T_float* heating=0, T_float* temp=0);


  template<typename T_input>
  unsigned int 
  process_block_thermal_equilibrium(const T_input* sigmaD, size_t sigmaP,
				    const T_input* esigmaD, size_t esigmaP,
				    const T_input* lambdaD, 
				    const T_input* elambdaD, 
				    const T_input* sizeD,
				    const T_float* sigmadlambdaD, size_t sdlP,
				    const T_float* esigmadlambdaD, size_t esdlP,
				    const T_input* dnD,
				    const T_input* intensity, 
				    const T_input* mdust, 
				    T_input* sed,
				    size_t ns, size_t nc, size_t nl, size_t nel, 
				    size_t nsPadded, size_t ncPadded, 
				    size_t nlPadded, size_t nelPadded,
				    T_float accuracy, 
				    bool add_to_sed=false, 
				    T_float* heating=0, T_float* temp=0, 
				    size_t ncfull=0);

  template<typename T_input>
  unsigned int 
  process_block_template_emission(const T_input* sigmaD, size_t sigmaP,
				  const T_input* lambdaD, 
				  const T_input* dlambdaD, 
				  const T_input* sizeD,
				  const T_float* sigmadlambdaD,
				  const T_input* dnD,
				  const T_input* intensity, 
				  const T_input* mdust, 
				  const T_input* template_emissionD,
				    T_input* sed,
				    size_t ns, size_t nc, size_t nl, 
				    size_t nsPadded, size_t ncPadded, size_t nlPadded,
				    T_float accuracy, 
				    bool add_to_sed=false, 
				    T_float* heating=0, T_float* temp=0, 
				    size_t ncfull=0);


  /** Initializes CUDA to run on the specified device. Returns false
      if CUDA initialization failed. */
  bool cuda_init(int cuda_dev);
};


#endif
